package org.dromara.system.kernel;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.PayApp;
import org.dromara.system.domain.bo.PayOrderBo;
import org.dromara.system.domain.bo.chart.OrderNumBo;
import org.dromara.system.domain.bo.chart.OrderChartBo;
import org.dromara.system.domain.vo.chart.*;
import org.dromara.system.mapper.*;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@RefreshScope
@Service
@RequiredArgsConstructor
public class OrderChartKernel {

    private final PayChartMapper payChartMapper;
    private final PayAppMapper payAppMapper;
    private final OrderSearchKernel orderSearchKernel;
    @Value("${hideOrder}")
    public Boolean hideOrder;
    @Value("${openCommission}")
    private Boolean openCommission;

    /**
     * 收款账号订单统计
     */
    public R<?> getAccountReceive(List<Long> accountIds) {

        Long agentId = null;
        Long supplierId = null;
        Long managerId = null;
        try {
            if (LoginHelper.isClient()) {
                return R.ok(new ArrayList<>());
            }
            if (LoginHelper.isAgent()) {
                agentId = LoginHelper.getUserId();
            }
            if (LoginHelper.isSupplier()) {
                supplierId = LoginHelper.getUserId();
            }
            if (LoginHelper.isManager()) {
                managerId = LoginHelper.getUserId();
            }
        } catch (Exception ignore) {
        }

        //查询今日收款信息
        List<AccountMoneyVo> todayMoneys = payChartMapper.selectAccountReceive(accountIds, DateUtils.getDate() + " 00:00:00", agentId, supplierId, managerId);
        Map<Long, AccountMoneyVo> todayMap = todayMoneys.stream().collect(Collectors.toMap(AccountMoneyVo::getAccountId, accountMoneyVo -> accountMoneyVo));

        //查询总收款信息
        List<AccountMoneyVo> allMoneys = payChartMapper.selectAccountReceive(accountIds, null, agentId, supplierId, managerId);
        Map<Long, AccountMoneyVo> allMap = allMoneys.stream().collect(Collectors.toMap(AccountMoneyVo::getAccountId, accountMoneyVo -> accountMoneyVo));

        //转换成账号的收款统计数据
        List<AccountMoneyCountVo> list = new ArrayList<>();
        for (Long accountId : accountIds) {
            AccountMoneyVo today = todayMap.get(accountId);
            AccountMoneyVo all = allMap.get(accountId);

            AccountMoneyCountVo countVo = new AccountMoneyCountVo();
            countVo.setAccountId(accountId);
            countVo.setTodayCount(today == null ? 0 : today.getCount());
            countVo.setTodayMoney(today == null ? BigDecimal.ZERO : today.getMoney());
            countVo.setAllCount(all == null ? 0 : all.getCount());
            countVo.setAllMoney(all == null ? BigDecimal.ZERO : all.getMoney());
            list.add(countVo);
        }

        return R.ok(list);
    }

    /**
     * 轮询组额度统计
     *
     * @param groupIds 轮询组ID列表
     * @return 结果
     */
    public R<?> getGroupAccountLimit(List<Long> groupIds) {

        Long agentId = null;
        try {
            if (LoginHelper.isAgent()) {
                agentId = LoginHelper.getUserId();
            }
        } catch (Exception ignore) {
        }

        if (groupIds.isEmpty()) {
            return R.ok(new ArrayList<>());
        }

        //轮询组额度统计
        List<GroupAccountLimitVo> groups = payChartMapper.selectGroupAccountLimit(groupIds, agentId);
        //计算剩余额度
        groups = groups.stream().peek(obj -> {
            if (obj.getTotal() == null) {
                obj.setTotal(BigDecimal.ZERO);
            } else {
                if (obj.getTotalLimit() == null || obj.getTotalLimit().compareTo(BigDecimal.ZERO) <= 0) {
                    obj.setMoney(BigDecimal.ZERO);
                } else {
                    obj.setMoney(obj.getTotalLimit().subtract(obj.getTotalMoney() == null ? BigDecimal.ZERO : obj.getTotalMoney()));
                }
            }
        }).toList();
        return R.ok(groups);
    }

    /**
     * 轮询组额度统计
     *
     * @param groupId 轮询组ID
     * @return 结果
     */
    public R<?> getGroupTypeAccountLimit(Long groupId) {

        Long agentId = null;
        try {
            if (LoginHelper.isAgent()) {
                agentId = LoginHelper.getUserId();
            }
        } catch (Exception ignore) {
        }

        if (groupId == null) {
            return R.ok(new ArrayList<>());
        }

        //轮询组额度统计
        List<GroupTypeAccountLimitVo> groups = payChartMapper.selectGroupTypeAccountLimit(groupId, agentId);
        //计算剩余额度
        groups = groups.stream().peek(obj -> {
            if (obj.getTotal() == null) {
                obj.setTotal(BigDecimal.ZERO);
            } else {
                if (obj.getTotalLimit() == null || obj.getTotalLimit().compareTo(BigDecimal.ZERO) <= 0) {
                    obj.setMoney(BigDecimal.ZERO);
                } else {
                    obj.setMoney(obj.getTotalLimit().subtract(obj.getTotalMoney() == null ? BigDecimal.ZERO : obj.getTotalMoney()));
                }
            }
        }).toList();
        return R.ok(groups);
    }

    /**
     * 应用收款统计
     *
     * @param appIds 应用ID列表
     * @return 结果
     */
    public R<?> getAppReceiveInfo(List<Long> appIds) {

        Long agentId = null;
        Long clientId = null;
        Long managerId = null;
        try {
            if (LoginHelper.isAgent()) {
                agentId = LoginHelper.getUserId();
            } else if (LoginHelper.isClient()) {
                clientId = LoginHelper.getUserId();
            } else if (LoginHelper.isManager()) {
                managerId = LoginHelper.getUserId();
            }
        } catch (Exception ignore) {
        }

        //应用收款统计
        List<AppReceiveVo> todayMoneys = payChartMapper.selectAppReceiveInfo(appIds, DateUtils.getDate() + " 00:00:00", agentId, clientId, managerId);

        Map<Long, AppReceiveVo> todayMap = new HashMap<>();
        if (!todayMoneys.isEmpty()) {
            todayMap = todayMoneys.stream().collect(Collectors.toMap(AppReceiveVo::getAppId, vo -> vo));
        }

        //查询应用轮询组ID
        List<PayApp> apps = payAppMapper.selectList(new LambdaQueryWrapper<PayApp>().in(PayApp::getAppId, appIds));
        Map<Long, Long> groupIdMap = apps.stream().filter(tmp -> tmp.getGroupId() != null).collect(Collectors.toMap(PayApp::getAppId, PayApp::getGroupId));

        //轮询组额度统计
        List<GroupAccountLimitVo> groups = new ArrayList<>();
        if (!groupIdMap.values().isEmpty()) {
            groups = payChartMapper.selectGroupAccountLimit(new ArrayList<>(groupIdMap.values()), agentId);
        }

        //计算剩余额度
        Map<Long, GroupAccountLimitVo> groupMap = new HashMap<>();
        for (GroupAccountLimitVo obj : groups) {
            if (obj.getTotal() == null) {
                obj.setTotal(BigDecimal.ZERO);
            } else {
                if (obj.getTotalLimit() == null || obj.getTotalLimit().compareTo(BigDecimal.ZERO) <= 0) {
                    obj.setMoney(BigDecimal.ZERO);
                } else {
                    obj.setMoney(obj.getTotalLimit().subtract(obj.getTotalMoney() == null ? BigDecimal.ZERO : obj.getTotalMoney()));
                }
            }
            groupMap.put(obj.getGroupId(), obj);
        }

        //组装数据
        List<AppReceiveVo> list = new ArrayList<>();
        for (Long appId : appIds) {
            AppReceiveVo today = todayMap.get(appId);
            if (today == null) {
                today = new AppReceiveVo();
                today.setAppId(appId);
                today.setMoney(BigDecimal.ZERO);
                today.setCount(0);
            }
            Long groupId = groupIdMap.get(appId);
            if (groupId != null) {
                GroupAccountLimitVo group = groupMap.get(groupId);
                if (group != null) {
                    today.setTotal(group.getTotal());
                    today.setLimit(group.getMoney());
                }
            }
            list.add(today);
        }

        return R.ok(list);
    }

    /**
     * 订单数量统计
     *
     * @param bo 订单数量统计对象
     * @return 订单数量统计结果
     */
    public R<?> getOrderCount(OrderNumBo bo) {

        if (StringUtils.isEmpty(bo.getStartTime()) || StringUtils.isEmpty(bo.getEndTime())) {
            bo.setStartTime(DateUtils.getDate() + " 00:00:00");
            bo.setEndTime(DateUtils.getDate() + " 23:59:59");
        }

        //构建查询条件
        SearchSourceBuilder searchSourceBuilder = buildQuery(bo);

        //添加必选的状态
        bo.getStatus().addAll(Arrays.asList(1, 2, 3));
        bo.setRefundStatus(List.of(2));

        //吃单数量和金额
        FilterAggregationBuilder filterEat = AggregationBuilders.filter("eat_filter", QueryBuilders.termQuery("isFeign", 1));
        ValueCountAggregationBuilder countEat = AggregationBuilders.count("eat_count").field("orderId");
        SumAggregationBuilder moneyEat = AggregationBuilders.sum("eat_money").field("usdMoney");
        filterEat.subAggregation(countEat).subAggregation(moneyEat);
        searchSourceBuilder.aggregation(filterEat);

        //订单状态 统计不同状态下的订单数量和总金额
        if (bo.getStatus() != null && !bo.getStatus().isEmpty()) {
            // 创建一个过滤器，用于过滤出符合订单状态条件的订单
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            boolQuery.must(QueryBuilders.termsQuery("status", bo.getStatus().stream().sorted().toList()));
            boolQuery.must(QueryBuilders.termQuery("isFeign", 0));
            FilterAggregationBuilder filterAgg = AggregationBuilders.filter("status_filter", boolQuery);

            // 在过滤器的基础上，创建一个terms聚合，用于统计不同订单状态下的订单数量和总金额
            TermsAggregationBuilder statusAgg = AggregationBuilders.terms("groupStatus").field("status");
            statusAgg.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));

            // 将terms聚合作为子聚合添加到过滤器聚合中
            filterAgg.subAggregation(statusAgg);

            // 将过滤器聚合添加到搜索源构建器中
            searchSourceBuilder.aggregation(filterAgg);
        }

        // 争议状态 统计不同状态下的订单数量和总金额
        if (bo.getDisputeStatus() != null && !bo.getDisputeStatus().isEmpty()) {
            // 创建一个过滤器，用于过滤出符合争议状态条件的订单
            FilterAggregationBuilder filterAgg = AggregationBuilders.filter("dispute_filter", QueryBuilders.termsQuery("disputeStatus", bo.getDisputeStatus()));

            // 在过滤器的基础上，创建一个terms聚合，用于统计不同争议状态下的订单数量和总金额
            TermsAggregationBuilder statusAgg1 = AggregationBuilders.terms("groupDisputeStatus").field("disputeStatus");
            statusAgg1.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));

            // 将terms聚合作为子聚合添加到过滤器聚合中
            filterAgg.subAggregation(statusAgg1);

            // 将过滤器聚合添加到搜索源构建器中
            searchSourceBuilder.aggregation(filterAgg);
        }

        // 退款状态 统计不同状态下的订单数量和总金额
        if (bo.getRefundStatus() != null && !bo.getRefundStatus().isEmpty()) {
            // 创建一个过滤器，用于过滤出符合退款状态条件的订单
            FilterAggregationBuilder filterAgg = AggregationBuilders.filter("refund_filter", QueryBuilders.termsQuery("refundStatus", bo.getRefundStatus()));

            // 在过滤器的基础上，创建一个terms聚合，用于统计不同退款状态下的订单数量和总金额
            TermsAggregationBuilder statusAgg2 = AggregationBuilders.terms("groupRefundStatus").field("refundStatus");
            statusAgg2.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));
            statusAgg2.subAggregation(AggregationBuilders.sum("sub_refund_money").field("refundMoney"));

            // 将terms聚合作为子聚合添加到过滤器聚合中
            filterAgg.subAggregation(statusAgg2);

            // 将过滤器聚合添加到搜索源构建器中
            searchSourceBuilder.aggregation(filterAgg);
        }

        // 物流状态 统计不同状态下的订单数量和总金额
        if (bo.getTrackStatus() != null && !bo.getTrackStatus().isEmpty()) {
            // 创建一个过滤器，用于过滤出符合物流状态条件的订单
            FilterAggregationBuilder filterAgg = AggregationBuilders.filter("track_filter", QueryBuilders.termsQuery("trackStatus", bo.getTrackStatus()));

            // 在过滤器的基础上，创建一个terms聚合，用于统计不同物流状态下的订单数量和总金额
            TermsAggregationBuilder statusAgg3 = AggregationBuilders.terms("groupTrackStatus").field("trackStatus");
            statusAgg3.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));

            // 将terms聚合作为子聚合添加到过滤器聚合中
            filterAgg.subAggregation(statusAgg3);

            // 将过滤器聚合添加到搜索源构建器中
            searchSourceBuilder.aggregation(filterAgg);
        }

        SearchResponse searchResponse = orderSearchKernel.highLevelSearchOrder(searchSourceBuilder);
        if (searchResponse != null) {
            // 解析聚合结果
            Aggregations aggregations = searchResponse.getAggregations();
            Map<String, Aggregation> aggregationMap = aggregations.asMap();

            JSONObject data = new JSONObject();

            //吃单数量 eat_filter eat_count eat_money
            ParsedFilter parsed = (ParsedFilter) aggregationMap.get("eat_filter");
            ParsedValueCount eatC = parsed.getAggregations().get("eat_count");
            ParsedSum eatS = parsed.getAggregations().get("eat_money");
            long eatCount = eatC.getValue();
            BigDecimal eatMoney = BigDecimal.valueOf(eatS.getValue()).setScale(2, RoundingMode.HALF_UP);

            // 解析订单状态聚合结果 status
            ParsedFilter parsed1 = (ParsedFilter) aggregationMap.get("status_filter");
            ParsedLongTerms longTerms1 = parsed1.getAggregations().get("groupStatus");

            long successCount = 0;
            BigDecimal successMoney = BigDecimal.ZERO;
            long errorCount = 0;
            BigDecimal errorMoney = BigDecimal.ZERO;
            long createCount = 0;
            for (Terms.Bucket bucket : longTerms1.getBuckets()) {
                long count = bucket.getDocCount();
                Long status = (Long) bucket.getKey();
                ParsedSum agg = bucket.getAggregations().get("sub_money");
                BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);
                data.put("status_" + status, new JSONObject().fluentPut("count", count).fluentPut("money", money));
                if (status == 1) {
                    createCount = count;
                }
                if (status == 2) {
                    successCount = count;
                    successMoney = money;
                }
                if (status == 3) {
                    errorCount = count;
                    errorMoney = money;
                }
            }

            // 解析争议状态聚合结果 dispute
            if (aggregationMap.containsKey("dispute_filter")) {
                ParsedFilter parsed2 = (ParsedFilter) aggregationMap.get("dispute_filter");
                ParsedLongTerms longTerms2 = parsed2.getAggregations().get("groupDisputeStatus");
                longTerms2.getBuckets().forEach(bucket -> {
                    long count = bucket.getDocCount();
                    Long status = (Long) bucket.getKey();
                    ParsedSum agg = bucket.getAggregations().get("sub_money");
                    BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);
                    data.put("dispute_" + status, new JSONObject().fluentPut("count", count).fluentPut("money", money));
                });
            }

            // 解析退款状态聚合结果 refund
            if (aggregationMap.containsKey("refund_filter")) {
                ParsedFilter parsed3 = (ParsedFilter) aggregationMap.get("refund_filter");
                ParsedLongTerms longTerms3 = parsed3.getAggregations().get("groupRefundStatus");
                longTerms3.getBuckets().forEach(bucket -> {
                    long count = bucket.getDocCount();
                    Long status = (Long) bucket.getKey();
                    ParsedSum agg = bucket.getAggregations().get(status == 2 ? "sub_refund_money" : "sub_money");//退款成功 取 退款金额 字段
                    BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);
                    data.put("refund_" + status, new JSONObject().fluentPut("count", count).fluentPut("money", money));
                });
            }

            // 解析物流状态聚合结果 track
            if (aggregationMap.containsKey("track_filter")) {
                ParsedFilter parsed4 = (ParsedFilter) aggregationMap.get("track_filter");
                ParsedLongTerms longTerms4 = parsed4.getAggregations().get("groupTrackStatus");
                longTerms4.getBuckets().forEach(bucket -> {
                    long count = bucket.getDocCount();
                    Long status = (Long) bucket.getKey();
                    ParsedSum agg = bucket.getAggregations().get("sub_money");
                    BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);
                    data.put("track_" + status, new JSONObject().fluentPut("count", count).fluentPut("money", money));
                });
            }

            //是否显示吃单
            if (bo.getIsFeign() && !LoginHelper.isClient() && !LoginHelper.isManager()) {
                data.put("eat", new JSONObject().fluentPut("count", eatCount).fluentPut("money", eatMoney));
            }

            //不算吃单,或者商户 失败订单要加上吃单的
            if (!bo.getIsFeign() || LoginHelper.isClient() || LoginHelper.isManager()) {
                //失败的订单+吃单
                errorCount = errorCount + eatCount;
                errorMoney = errorMoney.add(eatMoney);

                data.put("status_3", new JSONObject().fluentPut("count", errorCount).fluentPut("money", errorMoney));
            } else {
                //成功订单+吃单
                successCount = successCount + eatCount;
                successMoney = successMoney.add(eatMoney);
            }

            //总订单数 = 支付成功 + 支付失败
            long totalCount = successCount + errorCount;
            BigDecimal totalMoney = successMoney.add(errorMoney);

            //计算成功率
            BigDecimal successRate = BigDecimal.ZERO;
            if (totalCount > 0 && successCount > 0) {
                successRate = new BigDecimal(successCount).divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
            }

            //计算转化率
            //总订单数 = 支付成功 + 支付失败 + 已创建
            long totalCount2 = totalCount + createCount;
            BigDecimal transformRate = BigDecimal.ZERO;
            if (totalCount2 > 0 && successCount > 0) {
                transformRate = new BigDecimal(successCount).divide(new BigDecimal(totalCount2), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
            }

            //总订单数量
            data.put("total", new JSONObject().fluentPut("count", totalCount).fluentPut("money", totalMoney).fluentPut("successRate", successRate).fluentPut("transformRate", transformRate));

            if (!LoginHelper.isClient()) {
                JSONObject refund_2 = data.getObject("refund_2", JSONObject.class);
                JSONObject status_2 = data.getObject("status_2", JSONObject.class);
                JSONObject eat = data.getObject("eat", JSONObject.class);
                if (refund_2 == null) {
                    refund_2 = new JSONObject().fluentPut("count", 0).fluentPut("money", 0);
                }
                if (status_2 == null) {
                    status_2 = new JSONObject().fluentPut("count", 0).fluentPut("money", 0);
                }
                if (eat == null) {
                    eat = new JSONObject().fluentPut("count", 0).fluentPut("money", 0);
                }

                Integer settCount = status_2.getInteger("count") + eat.getInteger("count") - refund_2.getInteger("count");
                BigDecimal settMoney = status_2.getBigDecimal("money").add(eat.getBigDecimal("money")).subtract(refund_2.getBigDecimal("money"));
                data.put("sett", new JSONObject().fluentPut("count", settCount).fluentPut("money", settMoney.setScale(2, RoundingMode.HALF_UP)));
            }

            return R.ok(data);
        }

        return R.fail();
    }

    /**
     * 订单成功率图表
     *
     * @param bo 参数
     * @return 结果
     */
    public R<?> getOrderSuccessRate(OrderChartBo bo) {

        if (StringUtils.isEmpty(bo.getStartTime()) || StringUtils.isEmpty(bo.getEndTime())) {
            bo.setStartTime(LocalDate.now().minusDays(6L) + " 00:00:00");
            bo.setEndTime(DateUtils.getDate() + " 23:59:59");
        }

        //构建查询条件
        SearchSourceBuilder searchSourceBuilder = buildQuery(bo);

        List<String> dateList = DateUtils.getDateList(bo.getStartTime(), bo.getEndTime());

        Map<String, BigDecimal> dateRate = new LinkedHashMap<>();
        Map<String, BigDecimal> transformRate = new LinkedHashMap<>();
        for (String date : dateList) {
            dateRate.put(date, new BigDecimal(0));
            transformRate.put(date, new BigDecimal(0));
        }

        try {
            TermsAggregationBuilder dayAgg = AggregationBuilders.terms("group_date").field("createDate").size(500);
            if (!bo.getIsFeign() || LoginHelper.isClient() || LoginHelper.isManager()) {
                //失败+吃单
                BoolQueryBuilder anQuery = QueryBuilders.boolQuery();
                anQuery.must(QueryBuilders.termQuery("status", 3));
                dayAgg.subAggregation(AggregationBuilders.filter("failed_orders", anQuery));
                //成功
                dayAgg.subAggregation(AggregationBuilders.filter("successful_orders", QueryBuilders.termQuery("status", 2)));
            } else {
                //成功+吃单
                dayAgg.subAggregation(AggregationBuilders.filter("successful_orders", QueryBuilders.termQuery("payStatus", 2)));

                //真实失败
                BoolQueryBuilder anQuery = QueryBuilders.boolQuery();
                anQuery.must(QueryBuilders.termQuery("status", 3));
                anQuery.must(QueryBuilders.termQuery("isFeign", 0));
                dayAgg.subAggregation(AggregationBuilders.filter("failed_orders", anQuery));
            }

            //已创建数量
            dayAgg.subAggregation(AggregationBuilders.filter("create_orders", QueryBuilders.termQuery("status", 1)));

            searchSourceBuilder.aggregation(dayAgg);

            SearchResponse searchResponse = orderSearchKernel.highLevelSearchOrder(searchSourceBuilder);
            if (searchResponse == null) {
                return R.fail("查询失败");
            }

            Aggregations aggregations = searchResponse.getAggregations();
            Terms dayTerms = aggregations.get("group_date");

            for (Terms.Bucket bucket : dayTerms.getBuckets()) {
                String date = bucket.getKeyAsString();
                long failed_orders = ((ParsedFilter) bucket.getAggregations().get("failed_orders")).getDocCount();
                long sucCount = ((ParsedFilter) bucket.getAggregations().get("successful_orders")).getDocCount();

                //总订单数量
                String dateStr = date.substring(0, 10);

                //成功率
                long totalCount = failed_orders + sucCount;
                if (totalCount > 0 && sucCount > 0) {
                    dateRate.put(dateStr, new BigDecimal(sucCount).divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP));
                }

                //转化率
                long createCount = ((ParsedFilter) bucket.getAggregations().get("create_orders")).getDocCount();
                totalCount = totalCount + createCount;//总订单数量+已创建
                if (totalCount > 0 && sucCount > 0) {
                    transformRate.put(dateStr, new BigDecimal(sucCount).divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP));
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return R.ok(new JSONObject().fluentPut("keys", dateRate.keySet()).fluentPut("values", dateRate.values()).fluentPut("transformRate", transformRate.values()));
    }

    /**
     * 订单各状态数量统计
     *
     * @param bo 参数
     * @return 结果
     */
    public R<?> getOrderStatusNum(OrderNumBo bo) {

        if (StringUtils.isEmpty(bo.getStartTime()) || StringUtils.isEmpty(bo.getEndTime())) {
            bo.setStartTime(LocalDate.now().minusDays(6L) + " 00:00:00");
            bo.setEndTime(DateUtils.getDate() + " 23:59:59");
        }

        //添加必选的状态
        bo.getStatus().addAll(Arrays.asList(1, 2, 3));

        //构建查询条件
        SearchSourceBuilder searchSourceBuilder = buildQuery(bo);

        List<String> dateList = DateUtils.getDateList(bo.getStartTime(), bo.getEndTime());

        Map<String, Object> statusMap = new LinkedHashMap<>();
        statusMap.put("total", 0);
        statusMap.put("eat", 0);

        //添加状态初始值
        bo.getStatus().forEach(status -> statusMap.put("status_" + status, 0));
        bo.getDisputeStatus().forEach(status -> statusMap.put("dispute_" + status, 0));
        bo.getRefundStatus().forEach(status -> statusMap.put("refund_" + status, 0));
        bo.getTrackStatus().forEach(status -> statusMap.put("track_" + status, 0));

        Map<String, Map<String, Object>> numMap = new LinkedHashMap<>();
        Map<String, Map<String, Object>> moneyMap = new LinkedHashMap<>();
        for (String date : dateList) {
            numMap.put(date, statusMap);
            moneyMap.put(date, statusMap);
        }

        try {
            //根据日期分组订单数量
            TermsAggregationBuilder dayAgg = AggregationBuilders.terms("group_date").field("createDate").size(500);

            //吃单数量
            FilterAggregationBuilder filterEat = AggregationBuilders.filter("eat_filter", QueryBuilders.termQuery("isFeign", 1));
            //金额
            filterEat.subAggregation(AggregationBuilders.sum("eat_money").field("usdMoney"));
            dayAgg.subAggregation(filterEat);

            //订单状态 统计不同状态下的订单数量和总金额
            if (bo.getStatus() != null && !bo.getStatus().isEmpty()) {
                // 创建一个过滤器，用于过滤出符合订单状态条件的订单
                BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
                boolQuery.must(QueryBuilders.termsQuery("status", bo.getStatus()));
                boolQuery.must(QueryBuilders.termQuery("isFeign", 0));
                FilterAggregationBuilder filterAgg = AggregationBuilders.filter("status_filter", boolQuery);

                // 在过滤器的基础上，创建一个terms聚合，用于统计不同订单状态下的订单数量和总金额
                TermsAggregationBuilder statusAgg = AggregationBuilders.terms("groupStatus").field("status");
                statusAgg.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));

                // 将terms聚合作为子聚合添加到过滤器聚合中
                filterAgg.subAggregation(statusAgg);

                // 将过滤器聚合添加到搜索源构建器中
                dayAgg.subAggregation(filterAgg);
            }

            // 争议状态 统计不同状态下的订单数量和总金额
            if (bo.getDisputeStatus() != null && !bo.getDisputeStatus().isEmpty()) {
                // 创建一个过滤器，用于过滤出符合争议状态条件的订单
                FilterAggregationBuilder filterAgg = AggregationBuilders.filter("dispute_filter", QueryBuilders.termsQuery("disputeStatus", bo.getDisputeStatus()));

                // 在过滤器的基础上，创建一个terms聚合，用于统计不同争议状态下的订单数量和总金额
                TermsAggregationBuilder statusAgg1 = AggregationBuilders.terms("groupDisputeStatus").field("disputeStatus");
                statusAgg1.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));

                // 将terms聚合作为子聚合添加到过滤器聚合中
                filterAgg.subAggregation(statusAgg1);

                // 将过滤器聚合添加到搜索源构建器中
                dayAgg.subAggregation(filterAgg);
            }

            // 退款状态 统计不同状态下的订单数量和总金额
            if (bo.getRefundStatus() != null && !bo.getRefundStatus().isEmpty()) {
                // 创建一个过滤器，用于过滤出符合退款状态条件的订单
                FilterAggregationBuilder filterAgg = AggregationBuilders.filter("refund_filter", QueryBuilders.termsQuery("refundStatus", bo.getRefundStatus()));

                // 在过滤器的基础上，创建一个terms聚合，用于统计不同退款状态下的订单数量和总金额
                TermsAggregationBuilder statusAgg2 = AggregationBuilders.terms("groupRefundStatus").field("refundStatus");
                statusAgg2.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));
                statusAgg2.subAggregation(AggregationBuilders.sum("sub_refund_money").field("refundMoney"));

                // 将terms聚合作为子聚合添加到过滤器聚合中
                filterAgg.subAggregation(statusAgg2);

                // 将过滤器聚合添加到搜索源构建器中
                dayAgg.subAggregation(filterAgg);
            }

            // 物流状态 统计不同状态下的订单数量和总金额
            if (bo.getTrackStatus() != null && !bo.getTrackStatus().isEmpty()) {
                // 创建一个过滤器，用于过滤出符合物流状态条件的订单
                FilterAggregationBuilder filterAgg = AggregationBuilders.filter("track_filter", QueryBuilders.termsQuery("trackStatus", bo.getTrackStatus()));

                // 在过滤器的基础上，创建一个terms聚合，用于统计不同物流状态下的订单数量和总金额
                TermsAggregationBuilder statusAgg3 = AggregationBuilders.terms("groupTrackStatus").field("trackStatus");
                statusAgg3.subAggregation(AggregationBuilders.sum("sub_money").field("usdMoney"));

                // 将terms聚合作为子聚合添加到过滤器聚合中
                filterAgg.subAggregation(statusAgg3);

                // 将过滤器聚合添加到搜索源构建器中
                dayAgg.subAggregation(filterAgg);
            }

            searchSourceBuilder.aggregation(dayAgg);

            SearchResponse searchResponse = orderSearchKernel.highLevelSearchOrder(searchSourceBuilder);
            if (searchResponse == null) {
                return R.fail("查询失败");
            }

            Aggregations aggregations = searchResponse.getAggregations();
            Terms dayTerms = aggregations.get("group_date");
            for (Terms.Bucket bucket : dayTerms.getBuckets()) {
                //日期
                String date = bucket.getKeyAsString();

                Map<String, Object> subMap1 = new HashMap<>(Map.copyOf(statusMap));
                Map<String, Object> subMap2 = new HashMap<>(Map.copyOf(statusMap));

                Map<String, Aggregation> aggregationMap = bucket.getAggregations().asMap();

                //总订单数量
                long total = 0;
                //总订单金额
                BigDecimal totalMoney = BigDecimal.ZERO;

                //吃单数量 eat_filter eat_count eat_money
                ParsedFilter parsed = (ParsedFilter) aggregationMap.get("eat_filter");
                ParsedSum eatS = parsed.getAggregations().get("eat_money");
                long eatCount = parsed.getDocCount();
                BigDecimal eatMoney = BigDecimal.valueOf(eatS.getValue()).setScale(2, RoundingMode.HALF_UP);

                //总订单数要加吃单
                total = total + eatCount;
                totalMoney = totalMoney.add(eatMoney);

                //计算吃单数量， 商户不返回吃单数据
                if (bo.getIsFeign() && !LoginHelper.isClient() && !LoginHelper.isManager()) {
                    subMap1.put("eat", eatCount);
                    subMap2.put("eat", eatMoney);
                }

                // 解析订单状态聚合结果 status
                ParsedFilter parsed1 = (ParsedFilter) aggregationMap.get("status_filter");
                ParsedLongTerms longTerms1 = parsed1.getAggregations().get("groupStatus");
                for (Terms.Bucket subBucket : longTerms1.getBuckets()) {
                    //状态
                    Long status = (Long) subBucket.getKey();

                    //数量
                    Long count = subBucket.getDocCount();

                    //金额
                    ParsedSum agg = subBucket.getAggregations().get("sub_money");
                    BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);

                    //真实成功 真实失败 加到总订单数
                    if (status == 2 || status == 3) {
                        total = total + count;
                        totalMoney = totalMoney.add(money);
                    }

                    //不计算吃单或者商户, 失败+吃单
                    if (status == 3 && (!bo.getIsFeign() || LoginHelper.isClient() || LoginHelper.isManager())) {
                        count = count + eatCount;
                        money = money.add(eatMoney);
                    }

                    subMap1.put("status_" + status, count);
                    subMap2.put("status_" + status, money);
                }

                // 解析争议状态聚合结果 dispute
                if (aggregationMap.containsKey("dispute_filter")) {
                    ParsedFilter parsed2 = (ParsedFilter) aggregationMap.get("dispute_filter");
                    ParsedLongTerms longTerms2 = parsed2.getAggregations().get("groupDisputeStatus");
                    longTerms2.getBuckets().forEach(subBucket -> {
                        //状态
                        Long status = (Long) subBucket.getKey();

                        //数量
                        Long count = subBucket.getDocCount();
                        subMap1.put("dispute_" + status, count);

                        //金额
                        ParsedSum agg = subBucket.getAggregations().get("sub_money");
                        BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);
                        subMap2.put("dispute_" + status, money);
                    });
                }

                // 解析退款状态聚合结果 refund
                if (aggregationMap.containsKey("refund_filter")) {
                    ParsedFilter parsed3 = (ParsedFilter) aggregationMap.get("refund_filter");
                    ParsedLongTerms longTerms3 = parsed3.getAggregations().get("groupRefundStatus");
                    longTerms3.getBuckets().forEach(subBucket -> {
                        //状态
                        Long status = (Long) subBucket.getKey();

                        //数量
                        Long count = subBucket.getDocCount();
                        subMap1.put("refund_" + status, count);

                        //金额
                        ParsedSum agg = subBucket.getAggregations().get(status == 2 ? "sub_refund_money" : "sub_money");//
                        BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);
                        subMap2.put("refund_" + status, money);
                    });
                }

                // 解析物流状态聚合结果 track
                if (aggregationMap.containsKey("track_filter")) {
                    ParsedFilter parsed4 = (ParsedFilter) aggregationMap.get("track_filter");
                    ParsedLongTerms longTerms4 = parsed4.getAggregations().get("groupTrackStatus");
                    longTerms4.getBuckets().forEach(subBucket -> {
                        //状态
                        Long status = (Long) subBucket.getKey();

                        //数量
                        Long count = subBucket.getDocCount();
                        subMap1.put("track_" + status, count);

                        //金额
                        ParsedSum agg = subBucket.getAggregations().get("sub_money");
                        BigDecimal money = BigDecimal.valueOf(agg.getValue()).setScale(2, RoundingMode.HALF_UP);
                        subMap2.put("track_" + status, money);
                    });
                }

                subMap1.put("total", total);
                subMap2.put("total", totalMoney);

                numMap.put(date.substring(0, 10), subMap1);
                moneyMap.put(date.substring(0, 10), subMap2);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return R.ok(new JSONObject().fluentPut("numMap", numMap).fluentPut("moneyMap", moneyMap));
    }

    /**
     * 获取排行榜列表
     *
     * @param bo 参数对象
     * @return 结果
     */
    public R<?> getOrderRanking(OrderChartBo bo) {

        if (StringUtils.isEmpty(bo.getStartTime()) || StringUtils.isEmpty(bo.getEndTime())) {
            bo.setStartTime(DateUtils.getDate() + " 00:00:00");
            bo.setEndTime(DateUtils.getDate() + " 23:59:59");
        }
        //构建查询条件
        SearchSourceBuilder searchSourceBuilder = buildQuery(bo);

        Map<String, List<JSONObject>> dateRate = new LinkedHashMap<>();
        Set<Long> appIds = new HashSet<>();

        try {
            // 总订单数前10
            TermsAggregationBuilder orderCountAgg = AggregationBuilders.terms("top_clients_order_count")
                .field("appId").size(bo.getRanking()).order(BucketOrder.aggregation("order_count", false));
            orderCountAgg.subAggregation(AggregationBuilders.filter("order_count", QueryBuilders.termsQuery("status", Arrays.asList(2, 3))));
            searchSourceBuilder.aggregation(orderCountAgg);

            // 成功订单数前10
            TermsAggregationBuilder statusCountAgg = AggregationBuilders.terms("top_clients_status_count")
                .field("appId").size(bo.getRanking()).order(BucketOrder.aggregation("status_2_count", false));
            statusCountAgg.subAggregation(AggregationBuilders.filter("status_2_count", QueryBuilders.termQuery(bo.getIsFeign() ? "payStatus" : "status", 2)));
            //聚合查询
            searchSourceBuilder.aggregation(statusCountAgg);
            SearchResponse searchResponse = orderSearchKernel.highLevelSearchOrder(searchSourceBuilder);
            if (searchResponse == null) {
                return R.fail("查询失败");
            }

            Aggregations aggregations = searchResponse.getAggregations();

            //总订单数前10
            Terms dayTerms = aggregations.get("top_clients_order_count");
            List<JSONObject> orderCount = new ArrayList<>();
            for (Terms.Bucket bucket : dayTerms.getBuckets()) {
                String appIdStr = bucket.getKeyAsString();
                appIds.add(Long.parseLong(appIdStr));
                long totalCount = ((ParsedFilter) bucket.getAggregations().get("order_count")).getDocCount();
                if (totalCount > 0) {
                    orderCount.add(new JSONObject().fluentPut("appId", appIdStr).fluentPut("count", totalCount));
                }
            }

            //成功订单数前10
            Terms statusTerms = aggregations.get("top_clients_status_count");
            List<JSONObject> successCount = new ArrayList<>();
            for (Terms.Bucket bucket : statusTerms.getBuckets()) {
                String appIdStr = bucket.getKeyAsString();
                appIds.add(Long.parseLong(appIdStr));
                long totalCount = ((ParsedFilter) bucket.getAggregations().get("status_2_count")).getDocCount();
                if (totalCount > 0) {
                    successCount.add(new JSONObject().fluentPut("appId", appIdStr).fluentPut("count", totalCount));
                }
            }

            //成功率排名前10
            SearchSourceBuilder rateSourceBuilder = buildQuery(bo);

            TermsAggregationBuilder dayAgg = AggregationBuilders.terms("top_clients_success_rate").field("appId");

            if (bo.getIsFeign()) {
                //成功+吃单
                dayAgg.subAggregation(AggregationBuilders.filter("successful_orders", QueryBuilders.termQuery("payStatus", 2)));

                //真实失败
                BoolQueryBuilder anQuery = QueryBuilders.boolQuery();
                anQuery.must(QueryBuilders.termQuery("status", 3));
                anQuery.must(QueryBuilders.termQuery("isFeign", 0));
                dayAgg.subAggregation(AggregationBuilders.filter("failed_orders", anQuery));
            } else {
                //失败+吃单
                BoolQueryBuilder anQuery = QueryBuilders.boolQuery();
                anQuery.must(QueryBuilders.termQuery("status", 3));
                dayAgg.subAggregation(AggregationBuilders.filter("failed_orders", anQuery));
                //成功
                dayAgg.subAggregation(AggregationBuilders.filter("successful_orders", QueryBuilders.termQuery("status", 2)));
            }

            //已创建数量
            dayAgg.subAggregation(AggregationBuilders.filter("create_orders", QueryBuilders.termQuery("status", 1)));

            rateSourceBuilder.aggregation(dayAgg);

            SearchResponse rateResponse = orderSearchKernel.highLevelSearchOrder(rateSourceBuilder);
            if (rateResponse == null) {
                return R.fail("查询失败");
            }
            Aggregations rateAgg = rateResponse.getAggregations();

            //组装数据
            Terms rateTerms = rateAgg.get("top_clients_success_rate");

            List<AbstractMap.SimpleEntry<String, BigDecimal>> transformRate = new ArrayList<>();

            List<JSONObject> rateList = rateTerms.getBuckets().stream()
                .map(bucket -> {
                    String appIdStr = bucket.getKeyAsString();
                    appIds.add(Long.parseLong(appIdStr));

                    long failed_orders = ((ParsedFilter) bucket.getAggregations().get("failed_orders")).getDocCount();
                    long sucCount = ((ParsedFilter) bucket.getAggregations().get("successful_orders")).getDocCount();

                    long totalCount = failed_orders + sucCount;

                    //成功率
                    BigDecimal rate = BigDecimal.ZERO;
                    if (totalCount > 0 && sucCount > 0) {
                        rate = new BigDecimal(sucCount).divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
                    }

                    //转化率
                    long createCount = ((ParsedFilter) bucket.getAggregations().get("create_orders")).getDocCount();
                    totalCount = totalCount + createCount;//总订单数量+已创建
                    if (totalCount > 0 && sucCount > 0) {
                        BigDecimal transRate = new BigDecimal(sucCount).divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
                        if (transRate.compareTo(BigDecimal.ZERO) > 0) {
                            transformRate.add(new AbstractMap.SimpleEntry<>(appIdStr, transRate));
                        }
                    }

                    return new AbstractMap.SimpleEntry<>(appIdStr, rate);
                }).filter(tmp -> tmp.getValue().compareTo(BigDecimal.ZERO) > 0).sorted(Map.Entry.<String, BigDecimal>comparingByValue().reversed()).limit(bo.getRanking())
                .map(entry -> new JSONObject().fluentPut("appId", entry.getKey()).fluentPut("count", entry.getValue())).toList();

            List<JSONObject> transformList = transformRate.stream().sorted(Map.Entry.<String, BigDecimal>comparingByValue().reversed()).limit(bo.getRanking())
                .map(entry -> new JSONObject().fluentPut("appId", entry.getKey()).fluentPut("count", entry.getValue())).toList();


            //成功订单金额前10
            if (bo.getIsFeign()) {
                bo.setPayStatus(2);
            } else {
                bo.setOrderStatus(2);
            }
            SearchSourceBuilder moneySourceBuilder = buildQuery(bo);

            //聚合查询
            TermsAggregationBuilder MoneySumAggregation = AggregationBuilders.terms("top_clients_money_sum")
                .field("appId").size(bo.getRanking()).order(BucketOrder.aggregation("money_sum", false))
                .subAggregation(AggregationBuilders.sum("money_sum").field("usdMoney"));
            moneySourceBuilder.aggregation(MoneySumAggregation);
            SearchResponse moneyResponse = orderSearchKernel.highLevelSearchOrder(moneySourceBuilder);
            if (moneyResponse == null) {
                return R.fail("查询失败");
            }
            Aggregations moneyAgg = moneyResponse.getAggregations();

            //组装数据
            Terms moneyTerms = moneyAgg.get("top_clients_money_sum");
            List<JSONObject> moneyCount = new ArrayList<>();
            for (Terms.Bucket bucket : moneyTerms.getBuckets()) {
                String appIdStr = bucket.getKeyAsString();
                appIds.add(Long.parseLong(appIdStr));
                double totalCount = ((ParsedSum) bucket.getAggregations().get("money_sum")).getValue();
                if (totalCount > 0) {
                    moneyCount.add(new JSONObject().fluentPut("appId", appIdStr).fluentPut("count", new BigDecimal(totalCount).setScale(2, RoundingMode.HALF_UP)));
                }
            }

            //查询应用上级信息
            Map<Long, PayApp> appMap;
            if (!appIds.isEmpty()) {
                List<PayApp> apps = payAppMapper.selectBatchIds(appIds);
                appMap = apps.stream().collect(Collectors.toMap(PayApp::getAppId, item -> item));
            } else {
                appMap = new HashMap<>();
            }

            if (!appMap.isEmpty()) {
                orderCount = orderCount.stream().peek(obj -> {
                    if (appMap.containsKey(Long.parseLong(obj.getString("appId")))) {
                        PayApp app = appMap.get(Long.parseLong(obj.getString("appId")));
                        obj.put("clientName", app.getClientName());
                        obj.put("agentName", app.getAgentName());
                    }
                }).toList();
                successCount = successCount.stream().peek(obj -> {
                    if (appMap.containsKey(Long.parseLong(obj.getString("appId")))) {
                        PayApp app = appMap.get(Long.parseLong(obj.getString("appId")));
                        obj.put("clientName", app.getClientName());
                        obj.put("agentName", app.getAgentName());
                    }
                }).toList();
                rateList = rateList.stream().peek(obj -> {
                    if (appMap.containsKey(Long.parseLong(obj.getString("appId")))) {
                        PayApp app = appMap.get(Long.parseLong(obj.getString("appId")));
                        obj.put("clientName", app.getClientName());
                        obj.put("agentName", app.getAgentName());
                    }
                }).toList();
                transformList = transformList.stream().peek(obj -> {
                    if (appMap.containsKey(Long.parseLong(obj.getString("appId")))) {
                        PayApp app = appMap.get(Long.parseLong(obj.getString("appId")));
                        obj.put("clientName", app.getClientName());
                        obj.put("agentName", app.getAgentName());
                    }
                }).toList();
                moneyCount = moneyCount.stream().peek(obj -> {
                    if (appMap.containsKey(Long.parseLong(obj.getString("appId")))) {
                        PayApp app = appMap.get(Long.parseLong(obj.getString("appId")));
                        obj.put("clientName", app.getClientName());
                        obj.put("agentName", app.getAgentName());
                    }
                }).toList();
            }

            dateRate.put("orderCount", orderCount);
            dateRate.put("successCount", successCount);
            dateRate.put("successRate", rateList);
            dateRate.put("transformRate", transformList);
            dateRate.put("moneyCount", moneyCount);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return R.ok(dateRate);
    }

    private SearchSourceBuilder buildQuery(OrderChartBo bo) {
        if (LoginHelper.isAgent()) {
            bo.setAgentId(LoginHelper.getUserId());
        } else if (LoginHelper.isClient()) {
            bo.setIsFeign(Boolean.FALSE);
            bo.getClientId().add(LoginHelper.getUserId());
            bo.setNotStatus(List.of(0));
        } else if (LoginHelper.isManager()) {
            bo.setIsFeign(Boolean.FALSE);
            bo.getManagerId().add(LoginHelper.getUserId());
            bo.setNotStatus(List.of(0));
        } else if (!LoginHelper.isSuperAdmin()) {
            bo.setIsFeign(Boolean.FALSE);
            bo.getClientId().add(LoginHelper.getUserId());
            bo.setNotStatus(List.of(0));
        }

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 构建查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //隐藏订单
        if (!LoginHelper.isSuperAdmin() && hideOrder) {
            boolQuery.mustNot(QueryBuilders.termQuery("hide", 1));
        }

        List<Integer> payTypes = bo.getPayType();
        Integer payStatus = bo.getPayStatus();
        Integer status = bo.getOrderStatus();
        List<Long> appIds = bo.getAppId();
        List<Long> accountIds = bo.getAccountIds();
        List<Long> groupIds = bo.getGroupIds();
        Long agentId = bo.getAgentId();
        List<Long> clientIds = bo.getClientId();
        List<Long> managerIds = bo.getManagerId();
        String startTime = bo.getStartTime();
        String endTime = bo.getEndTime();
        String groupTypeRemark = bo.getGroupTypeRemark();
        //收款平台
        if (payTypes != null && !payTypes.isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("payTypeId", payTypes));
        }
        if (status != null) {
            boolQuery.filter(QueryBuilders.termQuery("status", status));
        }
        if (payStatus != null) {
            boolQuery.filter(QueryBuilders.termQuery("payStatus", payStatus));
        }
        if (appIds != null && !appIds.isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("appId", appIds));
        }
        if (accountIds != null && !accountIds.isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("accountId", accountIds));
        }
        if (groupIds != null && !groupIds.isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("groupId", groupIds));
        }
        if (agentId != null) {
            boolQuery.filter(QueryBuilders.termQuery("agentId", agentId));
        }
        if (clientIds != null && !clientIds.isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("clientId", clientIds));
        }
        if (managerIds != null && !managerIds.isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("managerId", managerIds));
        }
        // 创建时间在指定范围内
        if (StringUtils.isNotBlank(startTime)) {
            boolQuery.filter(QueryBuilders.rangeQuery("createTime").from(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime).getTime()).includeLower(true));
        }
        if (StringUtils.isNotBlank(endTime)) {
            boolQuery.filter(QueryBuilders.rangeQuery("createTime").to(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime).getTime()).includeUpper(true));
        }
        if (bo.getNotStatus() != null && !bo.getNotStatus().isEmpty()) {
            if (bo.getNotStatus().size() == 1) {
                boolQuery.mustNot(QueryBuilders.termQuery("status", bo.getNotStatus().get(0)));
            } else {
                boolQuery.mustNot(QueryBuilders.termsQuery("status", bo.getNotStatus()));
            }
        }

        if (StringUtils.isNotBlank(groupTypeRemark)) {
            boolQuery.filter(new TermQueryBuilder("groupTypeRemark.keyword", groupTypeRemark));
        }

        searchSourceBuilder.query(boolQuery);

        return searchSourceBuilder;
    }

    public Map<String, Object> queryCount(PayOrderBo bo) {

        if (LoginHelper.isSupplier()) {
            return supplerQueryCount(bo);
        }

        boolean isClient = LoginHelper.isClient() || LoginHelper.isManager();
        boolean agentCmi = openCommission && (LoginHelper.isSuperAdmin() || LoginHelper.isAgent());
        boolean clientCmi = openCommission && (LoginHelper.isSuperAdmin() || LoginHelper.isAgent() || LoginHelper.isClient());

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(orderSearchKernel.buildQueryBuilder(bo));

        //统计支付成功数量
        searchSourceBuilder.aggregation(AggregationBuilders.filter("success_count", QueryBuilders.termQuery("status", 2)).subAggregation(AggregationBuilders.sum("money_sum").field("usdMoney")));
        //统计退款数量
        searchSourceBuilder.aggregation(AggregationBuilders.filter("refund_count", QueryBuilders.termQuery("refundStatus", 2)).subAggregation(AggregationBuilders.sum("money_sum").field("refundMoney")));
        //统计代理佣金
        if (agentCmi) {
            searchSourceBuilder.aggregation(AggregationBuilders.filter("agent_count", QueryBuilders.termQuery("status", 2)).subAggregation(AggregationBuilders.sum("money_sum").field("agentCommission")));
        }
        //统计商户佣金
        if (clientCmi) {
            searchSourceBuilder.aggregation(AggregationBuilders.filter("client_count", QueryBuilders.termQuery("status", 2)).subAggregation(AggregationBuilders.sum("money_sum").field("clientCommission")));
        }
        if (!isClient) {
            //统计吃单数量
            searchSourceBuilder.aggregation(AggregationBuilders.filter("eat_count", QueryBuilders.termQuery("isFeign", 1)).subAggregation(AggregationBuilders.sum("money_sum").field("usdMoney")));
        }

        searchSourceBuilder.size(0); // 设置返回结果数量为0，只获取聚合结果

        Map<String, Object> result = new LinkedHashMap<>();
        result.put("successCount", 0);
        result.put("successTotal", 0);
        result.put("refundCount", 0);
        result.put("refundTotal", 0);
        //佣金
        result.put("agentCommission", 0);
        result.put("clientCommission", 0);

        if (!isClient) {
            result.put("eatCount", 0);
            result.put("eatTotal", 0);
            result.put("settCount", 0);
            result.put("settTotal", 0);
        }

        // 执行查询，获取结果
        SearchResponse searchResponse = orderSearchKernel.highLevelSearchOrder(searchSourceBuilder);
        if (searchResponse == null) {
            return result;
        }

        // 解析聚合结果
        Aggregations aggregations = searchResponse.getAggregations();

        // 解析成功的订单数量和总金额
        ParsedFilter successFilter = aggregations.get("success_count");
        ParsedSum sum = successFilter.getAggregations().get("money_sum");
        Long successCount = successFilter.getDocCount();
        BigDecimal successTotal = BigDecimal.valueOf(sum.getValue()).setScale(2, RoundingMode.HALF_UP);
        result.put("successCount", successCount);
        result.put("successTotal", successTotal);

        ParsedFilter refundFilter = aggregations.get("refund_count");
        ParsedSum sum2 = refundFilter.getAggregations().get("money_sum");
        Long refundCount = refundFilter.getDocCount();
        BigDecimal refundTotal = BigDecimal.valueOf(sum2.getValue()).setScale(2, RoundingMode.HALF_UP);
        result.put("refundCount", refundCount);
        result.put("refundTotal", refundTotal);

        if (agentCmi) {
            ParsedFilter agentFilter = aggregations.get("agent_count");
            ParsedSum sum3 = agentFilter.getAggregations().get("money_sum");
            BigDecimal agentTotal = BigDecimal.valueOf(sum3.getValue()).setScale(2, RoundingMode.HALF_UP);
            result.put("agentCommission", agentTotal);
        }

        if (clientCmi) {
            ParsedFilter clientFilter = aggregations.get("client_count");
            ParsedSum sum4 = clientFilter.getAggregations().get("money_sum");
            BigDecimal clientTotal = BigDecimal.valueOf(sum4.getValue()).setScale(2, RoundingMode.HALF_UP);
            result.put("clientCommission", clientTotal);
        }

        if (!isClient) {
            ParsedFilter eat_count = aggregations.get("eat_count");
            ParsedSum sum3 = eat_count.getAggregations().get("money_sum");
            Long eatCount = eat_count.getDocCount();
            BigDecimal eatTotal = BigDecimal.valueOf(sum3.getValue()).setScale(2, RoundingMode.HALF_UP);
            result.put("eatCount", eatCount);
            result.put("eatTotal", eatTotal);

            result.put("settCount", successCount + eatCount - refundCount);
            result.put("settTotal", successTotal.add(eatTotal).subtract(refundTotal));
        }

        return result;
    }

    /**
     * 查询订单数量/金额汇总
     *
     * @param bo 查询条件
     * @return R<?>
     */
    public Map<String, Object> supplerQueryCount(PayOrderBo bo) {

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(orderSearchKernel.buildQueryBuilder(bo));

        //统计支付成功数量
        searchSourceBuilder.aggregation(AggregationBuilders.filter("success_count", QueryBuilders.termQuery("status", 2)).subAggregation(AggregationBuilders.sum("money_sum").field("usdMoney")));
        //统计退款数量
        searchSourceBuilder.aggregation(AggregationBuilders.filter("refund_count", QueryBuilders.termQuery("refundStatus", 2)).subAggregation(AggregationBuilders.sum("money_sum").field("refundMoney")));
        //统计吃单数量
        searchSourceBuilder.aggregation(AggregationBuilders.filter("eat_count", QueryBuilders.termQuery("isFeign", 1)).subAggregation(AggregationBuilders.sum("money_sum").field("usdMoney")));
        searchSourceBuilder.size(0); // 设置返回结果数量为0，只获取聚合结果

        Map<String, Object> result = new LinkedHashMap<>();
        result.put("refundCount", 0);
        result.put("refundTotal", 0);
        result.put("settCount", 0);
        result.put("settTotal", 0);

        // 执行查询，获取结果
        SearchResponse searchResponse = orderSearchKernel.highLevelSearchOrder(searchSourceBuilder);
        if (searchResponse == null) {
            return result;
        }

        // 解析聚合结果
        Aggregations aggregations = searchResponse.getAggregations();

        // 解析成功的订单数量和总金额
        ParsedFilter successFilter = aggregations.get("success_count");
        ParsedSum sum = successFilter.getAggregations().get("money_sum");
        Long successCount = successFilter.getDocCount();
        BigDecimal successTotal = BigDecimal.valueOf(sum.getValue()).setScale(2, RoundingMode.HALF_UP);

        ParsedFilter refundFilter = aggregations.get("refund_count");
        ParsedSum sum2 = refundFilter.getAggregations().get("money_sum");
        Long refundCount = refundFilter.getDocCount();
        BigDecimal refundTotal = BigDecimal.valueOf(sum2.getValue()).setScale(2, RoundingMode.HALF_UP);
        result.put("refundCount", refundCount);
        result.put("refundTotal", refundTotal);

        ParsedFilter eat_count = aggregations.get("eat_count");
        ParsedSum sum3 = eat_count.getAggregations().get("money_sum");
        Long eatCount = eat_count.getDocCount();
        BigDecimal eatTotal = BigDecimal.valueOf(sum3.getValue()).setScale(2, RoundingMode.HALF_UP);

        result.put("settCount", successCount + eatCount - refundCount);
        result.put("settTotal", successTotal.add(eatTotal).subtract(refundTotal));
        return result;
    }

    /**
     * 查询轮询组收款账号的收款金额
     *
     * @param groupAccountIds 轮询组账号ID
     * @return 结构
     */
    public Map<Long, BigDecimal> getGroupAccountMoney(Set<Long> groupAccountIds) {
        Map<Long, BigDecimal> result = new HashMap<>();

        if (groupAccountIds == null || groupAccountIds.isEmpty()) {
            return result;
        }

        // 构建查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termsQuery("groupAccountId", groupAccountIds));
        boolQuery.must(QueryBuilders.termQuery("payStatus", 2));//真实成功订单
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQuery);

        TermsAggregationBuilder dayAgg = AggregationBuilders.terms("group_account").field("groupAccountId");
        dayAgg.subAggregation(AggregationBuilders.sum("money").field("usdMoney"));
        searchSourceBuilder.aggregation(dayAgg);

        SearchResponse searchResponse = orderSearchKernel.highLevelSearchOrder(searchSourceBuilder);
        if (searchResponse == null) {
            return result;
        }

        Aggregations aggregations = searchResponse.getAggregations();
        Terms dayTerms = aggregations.get("group_account");
        for (Terms.Bucket bucket : dayTerms.getBuckets()) {
            long groupAccountId = bucket.getKeyAsNumber().longValue();
            ParsedSum moneySum = bucket.getAggregations().get("money");
            double money = moneySum.getValue();
            result.put(groupAccountId, new BigDecimal(money).setScale(2, RoundingMode.HALF_UP));
        }

        return result;
    }
}
